from django.shortcuts import render
from django.views import View
# Create your views here.
from apps.users.models import User, Address
from django import http
import json,re,logging

from meiduo_mall.utils.secret import SecretOauth

logger = logging.getLogger('django')
from django.contrib.auth import logout
from django.contrib.auth import login,authenticate
from meiduo_mall.utils.views import LoginRequiredJSONMixin


class CreateAddressView(View):

    def post(self,request):

        # 获取地址个数
        count = Address.objects.filter(user=request.user, is_deleted=False).count()
        # 判断是否超过上限
        if count >= 20:
            return http.JsonResponse({'code':400,'errmsg':'地址数量超过上限'})
        # 1. 接受参数
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 2. 校验参数
        # 判断参数化是否齐全
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code':400,'errmsg':'参数不齐全'})
        # 判断手机号正则
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return http.JsonResponse({'code': 400, 'errmsg': '手机号格式不正确'})
        # 判断tel正则
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.JsonResponse({'code': 400,  'errmsg': '参数tel有误'})
        # 判断email正则
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.JsonResponse({'code': 400, 'errmsg': '参数email有误'})

        # 3. 保存地址信息
        try:
            address = Address.objects.create(
                user = request.user,
                title = receiver,
                receiver = receiver,
                province_id = province_id,
                city_id = city_id,
                district_id = district_id,
                place = place,
                mobile = mobile,
                tel = tel,
                email = email
            )
        # 4. 设置默认地址
            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code':400,'errmsg':'添加失败'})
        # 5. 将新增的地址响应给前端
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        # 6. 响应结果
        return http.JsonResponse({'code':0,'errmsg':'ok','address':address_dict})


class VerifyEmailView(View):
    def put(self,request):
        # 接收token
        token = request.GET.get('token')
        if not token:
            return http.JsonResponse({'code':400,'errmsg':'token缺少'})
        # 解密
        data_dict = SecretOauth().loads(token)

        # 取数据库对比 user_id email
        try:
           user = User.objects.get(pk=data_dict.get('user_id'),email=data_dict.get('email'))
        except Exception as e:
            print(e)
            return http.JsonResponse({'code':400,'errmsg':'参数有误'})

        # 修改激活状态
        user.email_active=True
        user.save()
        return http.JsonResponse({'code':0,'errmsg':'激活成功'})



class EmailView(View):

    def put(self,request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        # 校验参数
        if not email:
            return http.JsonResponse({'code':400,'errmsg':'缺少email参数'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({'code': 400,
                                      'errmsg': '参数email有误'})
        # 赋值email字段
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code':400,'errmsg':'添加邮箱失败'})
        # 调用发送的函数
        from apps.users.utils import generate_verify_email_url
        verify_url = generate_verify_email_url(request)
        from celery_tasks.email.tasks import send_verify_email
        send_verify_email.delay(email, verify_url)
        return http.JsonResponse({'code':0,'errmsg':'添加成功'})

class UserInfoView(LoginRequiredJSONMixin,View):
    def get(self,request):
        info_data = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }

        # 返回响应
        return http.JsonResponse({'code':0,
                                  'errmsg':'ok',
                                  'info_data':info_data})


class LogoutView(View):
    def delete(self,request):
        # 清理session
        logout(request)
        # 创建response对象
        response = http.JsonResponse({'code':0,'errmsg':'ok'})
        # 调用对象 delete_cookie方法
        response.delete_cookie('username')
        return response


class LoginView(View):
    def post(self,request):
        # 接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        remembered = dict.get('remembered')
        # 校验参数
        if not all([username,password]):
            return http.JsonResponse({'code':400,'errmsg':'参数不全'})

        # 验证是否能够登录
        user = authenticate(username=username,password=password)
        # 判断是否为空
        if user is None:
            return http.JsonResponse({'code':400,'errmsg':'用户名或密码错误'})
        # 保持状态
        login(request,user)
        # 判断是否记住登录
        if remembered != True:
            # 不记住登录
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        response = http.JsonResponse({'code':0,'errmsg':'登录成功'})
        response.set_cookie('username',user.username,max_age=3600*24*14)
        # 返回结果
        return response

class RegisterView(View):
    """
    方式: POST
    地址: /register/
    参数 username password  password2 mobile sms_code allow
    响应结果 code errmsg
    """
    def post(self,request):
        # 1. 接收参数
        json_dict = json.loads(request.body.decode())
        # 2. 提取参数
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        allow = json_dict.get('allow')
        sms_code = json_dict.get('sms_code')
        # 校验参数
        # 判断是否为空
        if not all([username,password,password2,mobile,sms_code]):
            return http.JsonResponse({'code':400,'errmsg':'缺少参数'})
        # username是否合法
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$',username):
            return http.JsonResponse({'code':400,'errmsg':'用户名格式有误'})
        # 密码是否合法
        if not re.match(r'^[a-zA-Z0-9]{8,20}$',password):
            return http.JsonResponse({'code': 400, 'errmsg': '密码格式有误'})
        # 两次密码是否一致
        if password != password2:
            return http.JsonResponse({'code': 400, 'errmsg': '两次密码不一致'})
        # 手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return http.JsonResponse({'code':400,'errmsg':'手机号格式有误'})
        # allow
        if allow !=True:
            return http.JsonResponse({'code':400,'errmsg':'allow格式有误'})


        # 注册的核心逻辑
        try:
            user = User.objects.create_user(username=username,password=password,mobile=mobile)
        except Exception as e:
            return http.JsonResponse({'code':400,'errmsg':'注册失败'})
        login(request,user)

        response = http.JsonResponse({'code':0,'errmsg':'注册成功'})
        response.set_cookie('username',user.username,max_age=3600*24*14)

        return response



class UsernameCountView(View):
    """
    请求方法: get
    请求地址: /usernames/(?P<username>[a-zA-Z0-9_-]{5,20})/count/
    参数: username 必传
    响应结果: code errmsg  count
    """
    def get(self,request,username):

        # 判断用户是否重复注册
        try:
            count = User.objects.filter(username=username).count()
        except Exception as e:
            return http.JsonResponse({'code':400,'errmsg':'查询数据库失败'})

        return http.JsonResponse({'code':0,'errmsg':'ok','count':count})


class MobileCountView(View):
    """
    请求方式: get
    地址 : /mobiles/(?P<mobile>1[3-9]\d{9}/count/
    参数: mobile 必传
    响应结果 code  errmsg count
    """
    def get(self,request,mobile):

        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return http.JsonResponse({'code':400,'errmsg':'查询失败'})
        return http.JsonResponse({'code':0,'errmsg':'ok'})
